//向某一文件输入当前时间，每小时更新一次
//用于记录系统上次开机时长
//g++ -std=c++23 record_time.cpp

#include <chrono>
#include <ctime>
#include <print>
#include <iostream>
#include <iomanip>
#include <string>
#include <format>
#include <stdexcept>
#include <fstream>
#include <filesystem>   

#include <asio/system_timer.hpp>
#include <asio.hpp>

using namespace asio;

std::string get_now();

awaitable<void> record_time(io_context &c, std::string filepath)
{
    auto now = get_now();
    std::println("开始 {}", now);
    steady_timer timer(c);
    std::ofstream ostrm(filepath);
    if (!ostrm)
    {
        throw std::runtime_error(std::format("failed to open file {}", filepath));
    }
    ostrm << now << "\n";
    ostrm.flush();
    auto rp = ostrm.tellp();
    while (true)
    {
        timer.expires_after(std::chrono::hours(1));
        co_await timer.async_wait(use_awaitable);
        ostrm.seekp(rp);
        now = get_now();
        std::println("{}", now);
        ostrm << now;
        ostrm.flush();
        std::filesystem::resize_file(filepath, ostrm.tellp()); 
    }
    std::println("结束 {}", get_now());
}

std::string get_now()
{
    return std::format("{}", std::chrono::zoned_time{std::chrono::current_zone(),
                                                     std::chrono::system_clock::now()});
}

int main(int argc, char *argv[])
{
    std::string path = "time_point_record.txt";
    if (argc >= 2)
    {
        path = argv[1];
    }
    io_context ctx;
    co_spawn(ctx, record_time(ctx, path), detached);
    ctx.run();
    return 0;
}